package cn.hy.dataSync.task;


import cn.hy.dataSync.config.ErrorLimit;
import cn.hy.dataSync.statistics.communication.Communication;
import cn.hy.dataSync.statistics.communication.CommunicationTool;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.Validate;

import java.util.Objects;

/**
 * 根据配置信息的 限制信息
 * 失败记录 校验
 */
@Slf4j
public final class ErrorRecordChecker {
    private final Long recordLimit;
    private Double percentageLimit;

    public ErrorRecordChecker(final ErrorLimit errorLimit) {
        this(errorLimit.getRecord(), errorLimit.getPercentage());
    }

    public ErrorRecordChecker(Long rec, Double percentage) {
        recordLimit = rec;
        percentageLimit = percentage;

        if (Objects.nonNull(percentageLimit)) {
            Validate.isTrue(0.0 <= percentageLimit && percentageLimit <= 1.0,
                    "脏数据百分比限制应该在[0.0, 1.0]之间");
        }

        if (Objects.nonNull(recordLimit)) {
            Validate.isTrue(recordLimit >= 0, "脏数据条数现在应该为非负整数");
            // errorRecord优先级高于errorPercentage.
            percentageLimit = null;
        }
    }

    public void checkRecordLimit(Communication communication) {
        if (Objects.isNull(recordLimit)) {
            return;
        }

        long errorNumber = CommunicationTool.getTotalErrorRecords(communication);
        if (recordLimit < errorNumber) {
            throw new RuntimeException(
                    String.format("脏数据条数检查不通过，限制是[%d]条，但实际上捕获了[%d]条.",
                            recordLimit, errorNumber));
        }
    }

    public void checkPercentageLimit(Communication communication) {
        if (Objects.isNull(percentageLimit)) {
            return;
        }

        long total = CommunicationTool.getTotalReadRecords(communication);
        long error = CommunicationTool.getTotalErrorRecords(communication);

        if (total > 0 && ((double) error / (double) total) > percentageLimit) {
            throw new RuntimeException(
                    String.format("脏数据百分比检查不通过，限制是[%f]，但实际上捕获到[%f].",
                            percentageLimit, ((double) error / (double) total)));
        }
    }
}
